package com.taxx.util;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Base64;

public class Sm4Util {

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 使用SM4-ECB模式加密文本
     *
     * @param plaintext 待加密的文本
     * @param key       16进制格式的密钥
     * @return 加密后的Base64编码字符串，如果加密失败则返回null
     */
    public static String encryptWithSm4Ecb(String plaintext, String key) {
        try {
            byte[] keyBytes = hexStringToByteArray(key);
            byte[] plaintextBytes = plaintext.getBytes(StandardCharsets.UTF_8);

            // 填充明文到块大小的倍数（SM4为16字节）
            int padLen = 16 - plaintextBytes.length % 16;
            byte[] paddedPlaintext = new byte[plaintextBytes.length + padLen];
            System.arraycopy(plaintextBytes, 0, paddedPlaintext, 0, plaintextBytes.length);
            for (int i = 0; i < padLen; i++) {
                paddedPlaintext[plaintextBytes.length + i] = (byte) padLen;
            }

            // 创建密码器
            Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS5Padding");
            SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "SM4");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);

            // 执行加密
            byte[] encryptedBytes = cipher.doFinal(paddedPlaintext);

            // 返回Base64编码的密文
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            System.err.println("加密过程出错: " + e.getMessage());
            return null;
        }
    }

    /**
     * 使用SM4-ECB模式解密文本
     *
     * @param ciphertext Base64编码的密文
     * @param key        16进制格式的密钥
     * @return 解密后的原文，如果解密失败则返回null
     */
    public static String decryptWithSm4Ecb(String ciphertext, String key) {
        try {
            byte[] keyBytes = hexStringToByteArray(key);
            byte[] ciphertextBytes = Base64.getDecoder().decode(ciphertext);

            // 创建密码器
            Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS5Padding");
            SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "SM4");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);

            // 执行解密
            byte[] decryptedBytes = cipher.doFinal(ciphertextBytes);

            // 返回解密后的明文
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            System.err.println("解密过程出错: " + e.getMessage());
            return null;
        }
    }

    /**
     * 将16进制字符串转换为字节数组
     *
     * @param hexString 16进制字符串
     * @return 字节数组
     */
    private static byte[] hexStringToByteArray(String hexString) {
        int len = hexString.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i + 1), 16));
        }
        return data;
    }

    // 测试代码
    public static void main(String[] args) {
        String key = "6118b85232f5ce2c2633520e8085cf77"; // 32位16进制字符串，16字节
        // 解密
        String encrypted = "3oTOfaM5Qxm3+ZZCP7jqOPrXBSLYcpypB7+RrfE0jjifGymuIhTQGeiRRzcSP03iObxV6W2qalG0dKII6mXN/5cXlpwf+xEc72a6CXOTLW5Mlkzartai88AF88mKfVq7";

        String decrypted = Sm4Util.decryptWithSm4Ecb(encrypted,key);
        System.out.println("解密结果: " + decrypted);
    }

}
